﻿using System;
using FrameworkManapro.BusinessModel;
using FrameworkManapro.Utilities;
using FrameworkManapro.WebUI;
namespace GMAC.ReportingSystem.Business.Components
{
    public class UserComponent : IBusinessComponent<Entities.User>
    {
        private DataAccess.UserDataAccess dac;

        public UserComponent()
        {
            dac = new DataAccess.UserDataAccess();
        }

        #region IBusinessComponent<User> Members

        public int Create(Entities.User entityToCreate)
        {
            if (Validate(entityToCreate))
            {
                entityToCreate.Password = EncriptarDescencriptar.Cifrar(entityToCreate.Password);
                var result = dac.Insert(entityToCreate);
                entityToCreate.Password = "";
                return result;
            }
            return 0;
        }

        public int Delete(Entities.User entityToDelete)
        {
            if (entityToDelete.UserID <= 0)
                throw new ArgumentOutOfRangeException("UserID", "Value must be greater than zero.");

            return dac.Delete(entityToDelete);
        }

        public int Edit(Entities.User entityToEdit)
        {
            if (entityToEdit.UserID <= 0)
                throw new ArgumentOutOfRangeException("UserID", "Value must be greater than zero.");

            return Validate(entityToEdit) ? dac.Update(entityToEdit) : 0;
        }

        public Entities.User GetDetails(object entityId)
        {
            return dac.Get(entityId);
        }

        protected bool Validate(Entities.User user)
        {
            if (user == null) throw new ArgumentNullException("user", "The argument cannot be null.");
            if (user.Role == null) throw new ArgumentNullException("Role", "The argument cannot be null.");
            if (user.Role.RoleID <= 0) throw new ArgumentOutOfRangeException("Role.RoleID", "Value must be greater than zero.");
            if (string.IsNullOrEmpty(user.Login)) throw new ArgumentNullException("Login", "The argument cannot be null.");
            if (string.IsNullOrEmpty(user.Name)) throw new ArgumentNullException("Name", "The argument canno be null.");

            //TODO: Validar longitud de los campos
            user.Login = user.Login.Trim().Left(50);
            user.Name = user.Name.Trim().Left(50);
            return true;
        }

        #endregion

        /// <summary>
        /// Receives the credentials of a User and tries to login in the application
        /// </summary>
        /// <param name="login">The login.</param>
        /// <param name="password">The password.</param>
        /// <returns>The User logged in. The method returns <c>null</c> if the credentials are invalid to perform a login.</returns>
        public Entities.User Login(string login, string password)
        {
            var user = dac.GetByLogin(login);
            if (user != null)
            {
                if (String.Compare(EncriptarDescencriptar.Descifrar(user.Password), password, false) == 0)
                {
                    user.LoginAttempts = 0;
                    dac.UpdateInvalidLoginAttempts(user);
                    return user;
                }
                else
                {
                    user.LoginAttempts++;
                    int maxInvalidPasswordAttempts;
                    if (int.TryParse(System.Configuration.ConfigurationManager.AppSettings["maxInvalidPasswordAttempts"], out maxInvalidPasswordAttempts))
                    {
                        if (user.LoginAttempts == maxInvalidPasswordAttempts)
                        {
                            user.LoginAttempts = 0;
                            user.Status = false;
                        }
                        dac.UpdateInvalidLoginAttempts(user);
                    }
                }
            }
            return null;
        }

        public Entities.User GetByLogin(string login)
        {
            return dac.GetByLogin(login);
        }

        /// <summary>
        /// Created by:   Michelle A. González A.
        /// Date:         04/08/2010
        /// Description:  Checks if there exists a user with the same login passed as a parameter.
        /// </summary>
        public Entities.User GetByLoginRepeat(string login, string userId)
        {
            return dac.GetByLoginRepeat(login, userId);
        }


        public Entities.UserCollection GetList()
        {
            return dac.GetList();
        }

        public Entities.UserCollection Search(string name, int? roleId, int? identificationNumber, string login , PagingDetails paging)
        {
            if (name == null) name = string.Empty;
            if (login == null) login = string.Empty;

            return dac.Search(name, roleId, identificationNumber, login, paging);
        }

        public void ChangePassword(Entities.User user)
        {
            user.Password = EncriptarDescencriptar.Cifrar(user.Password);
            dac.ChangePassword(user);
            user.Password = string.Empty;

        }
        public void ResetPassword(Entities.User user)
        {
            dac.ChangePassword(user);
        }
    }
}
